package cn.wolfcode.p2p.business.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import cn.wolfcode.p2p.base.domain.Account;
import cn.wolfcode.p2p.base.domain.UserInfo;
import cn.wolfcode.p2p.base.exception.DisplayableException;
import cn.wolfcode.p2p.base.service.IAccountService;
import cn.wolfcode.p2p.base.service.IUserInfoService;
import cn.wolfcode.p2p.base.util.AssertUtil;
import cn.wolfcode.p2p.base.util.BitStateUtil;
import cn.wolfcode.p2p.base.util.Constants;
import cn.wolfcode.p2p.base.util.DateUtil;
import cn.wolfcode.p2p.base.util.UserContext;
import cn.wolfcode.p2p.business.domain.Bid;
import cn.wolfcode.p2p.business.domain.BidRequest;
import cn.wolfcode.p2p.business.domain.BidRequestAuditHistory;
import cn.wolfcode.p2p.business.domain.CreditTransfer;
import cn.wolfcode.p2p.business.domain.PaymentSchedule;
import cn.wolfcode.p2p.business.domain.PaymentScheduleDetail;
import cn.wolfcode.p2p.business.mapper.BidMapper;
import cn.wolfcode.p2p.business.mapper.BidRequestAuditHistoryMapper;
import cn.wolfcode.p2p.business.mapper.BidRequestMapper;
import cn.wolfcode.p2p.business.mapper.PaymentScheduleDetailMapper;
import cn.wolfcode.p2p.business.mapper.PaymentScheduleMapper;
import cn.wolfcode.p2p.business.query.BidRequestQueryObject;
import cn.wolfcode.p2p.business.query.PaymentScheduleQueryObject;
import cn.wolfcode.p2p.business.service.IAccountFlowService;
import cn.wolfcode.p2p.business.service.IBidRequestService;
import cn.wolfcode.p2p.business.service.ICreditTransferService;
import cn.wolfcode.p2p.business.service.ISystemAccountService;
import cn.wolfcode.p2p.business.util.CalculatetUtil;

@Service
@Transactional
public class BidRequestServiceImpl implements IBidRequestService {

	@Autowired
	private BidRequestMapper bidRequestMapper;

	@Autowired
	private IUserInfoService userinfoService;

	@Autowired
	private IAccountService accountService;

	@Autowired
	private BidRequestAuditHistoryMapper historyMapper;

	@Autowired
	private BidMapper bidMapper;

	@Autowired
	private IAccountFlowService flowService;

	@Autowired
	private ISystemAccountService systemAccountService;

	@Autowired
	private PaymentScheduleMapper psMapper;

	@Autowired
	private PaymentScheduleDetailMapper psdMapper;

	@Autowired
	private ICreditTransferService creditTransferService;

	@Override
	public BidRequest get(Long id) {
		return this.bidRequestMapper.selectByPrimaryKey(id);
	}

	@Override
	public PageInfo<BidRequest> query(BidRequestQueryObject qo) {
		PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize());
		List<BidRequest> list = this.bidRequestMapper.queryData(qo);
		return new PageInfo<>(list);
	}

	@Override
	public PageInfo<PaymentSchedule> queryPaymentSchedules(PaymentScheduleQueryObject qo) {
		PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize());
		List<PaymentSchedule> list = this.psMapper.queryData(qo);
		return new PageInfo<>(list);
	}

	@Override
	public void apply(BidRequest to) {
		// 检查
		UserInfo current = this.userinfoService.get(UserContext.getCurrent().getId());
		Account account = this.accountService.get(current.getId());

		if (current.getHasBasicInfo() && current.getHasRealAuth() && current.getHasVideoAuth()// 1,是否能借款;
				&& !current.getHasBidRequestInProcess()// 2,是否有借款在审核流程当中;
				&& to.getBidRequestAmount().compareTo(account.getRemainBorrowLimit()) <= 0// 借款金额<=剩余可用额度
				&& to.getBidRequestAmount().compareTo(Constants.BORROW_AMOUNT_MIN) >= 0// 3,系统最小借款金额<=借款金额
				&& to.getCurrentRate().compareTo(new BigDecimal("20.0000")) <= 0// 利息<=20
				&& to.getCurrentRate().compareTo(new BigDecimal("5.0000")) >= 0// 5<=利息
				&& to.getMinBidAmount().compareTo(Constants.BID_AMOUNT_MIN) >= 0// 5,最小投标金额>=系统最小投标金额
		) {
			// 借款
			// 1,创建一个借款对象,设置数据;
			BidRequest br = new BidRequest();
			br.setApplyTime(new Date());
			br.setBidRequestAmount(to.getBidRequestAmount());
			br.setBidRequestState(Constants.BIDREQUEST_STATE_APPLY);
			br.setBidRequestType(Constants.BIDREQUEST_TYPE_NORMAL);
			br.setCreateUser(UserContext.getCurrent());
			br.setCurrentRate(to.getCurrentRate());
			br.setDescription(to.getDescription());
			br.setDisableDays(to.getDisableDays());
			br.setMinBidAmount(to.getMinBidAmount());
			br.setMonthes2Return(to.getMonthes2Return());
			br.setReturnType(to.getReturnType());
			br.setTitle(to.getTitle());
			br.setTotalRewardAmount(CalculatetUtil.calTotalInterest(br.getReturnType(), br.getBidRequestAmount(),
					br.getCurrentRate(), br.getMonthes2Return()));

			this.bidRequestMapper.insert(br);
			// 借款人,添加状态吗
			current.addState(BitStateUtil.HAS_BIDREQUEST_IN_PROCESS);
			this.userinfoService.update(current);
		}
	}

	@Override
	public void update(BidRequest br) {
		int count = bidRequestMapper.updateByPrimaryKey(br);
		if (count == 0) {
			System.out.println("乐观锁异常,BidRequest:" + br.getId());
			throw new DisplayableException("系统繁忙,请重试");
		}
	}

	/**
	 * 创建借款审核对象
	 * 
	 * @param br
	 * @param remark
	 * @param state
	 * @param auditType
	 */
	private void createBidRequestAuditHistory(BidRequest br, String remark, int state, int auditType) {
		BidRequestAuditHistory history = new BidRequestAuditHistory();
		history.setApplier(br.getCreateUser());
		history.setApplyTime(br.getApplyTime());
		history.setAuditor(UserContext.getCurrent());
		history.setAuditTime(new Date());
		history.setAuditType(auditType);
		history.setBidRequestId(br.getId());
		history.setRemark(remark);
		history.setState(state);
		this.historyMapper.insert(history);
	}

	@Override
	public void publishAudit(Long id, int state, String remark, Date publishTime) {
		// 判断,借款处于发表前审核状态;
		BidRequest br = this.bidRequestMapper.selectByPrimaryKey(id);
		if (br != null && br.getBidRequestState() == Constants.BIDREQUEST_STATE_APPLY) {
			// 创建一个借款审核对象,设置相关的属性值;
			this.createBidRequestAuditHistory(br, remark, state, BidRequestAuditHistory.AUDIT_PUBLISH);
			// 如果审核通过
			if (state == BidRequestAuditHistory.STATE_PASS) {
				if (publishTime != null) {
					// 处理定时发标
					br.setBidRequestState(Constants.BIDREQUEST_STATE_PUBLISH_PENDING);
					// 设置发标时间/到期时间
					br.setPublishTime(publishTime);
					br.setDisableDate(DateUtil.addDays(publishTime, br.getDisableDays()));
				} else {
					// 1,修改借款状态;
					br.setBidRequestState(Constants.BIDREQUEST_STATE_BIDDING);
					// 2,设置借款发表时间/到期时间/风控意见
					br.setPublishTime(new Date());
					br.setDisableDate(DateUtil.addDays(new Date(), br.getDisableDays()));
				}
				br.setNote(remark);
			} else {
				// 如果审核拒绝
				// 1,修改借款状态
				br.setBidRequestState(Constants.BIDREQUEST_STATE_PUBLISH_REFUSE);
				br.setNote(remark);
				// 2,去掉用户相关状态吗
				UserInfo applier = this.userinfoService.get(br.getCreateUser().getId());
				applier.removeState(BitStateUtil.HAS_BIDREQUEST_IN_PROCESS);
				this.userinfoService.update(applier);
			}
			this.update(br);
		}
	}

	@Override
	public void bid(Long bidRequestId, BigDecimal amount) {
		BidRequest br = this.get(bidRequestId);
		if (br != null) {
			Account borrowAccount = this.accountService.get(UserContext.getCurrent().getId());
			// 检查:

			if (amount.compareTo(br.getMinBidAmount()) >= 0// 1,投标金额>=最小投标金额
					&& amount.compareTo(borrowAccount.getUsableAmount().min(br.getRemainAmount())) <= 0// 2,投标金额<=min(用户可用余额,剩余借款金额)
					&& br.getBidRequestState() == Constants.BIDREQUEST_STATE_BIDDING// 3,借款处于招标状态
					&& !borrowAccount.getId().equals(br.getCreateUser().getId())// 4,当前用户是正常投资人
					&& !new Date().after(br.getDisableDate())// 5,没有超过招标时间
			) {
				// 投标:
				// 1,创建一个投标对象,设置属性
				Bid bid = new Bid();
				bid.setActualRate(br.getCurrentRate());
				bid.setAvailableAmount(amount);
				bid.setBidRequestId(br.getId());
				bid.setBidRequestState(br.getBidRequestState());
				bid.setBidRequestTitle(br.getTitle());
				bid.setBidTime(new Date());
				bid.setBidUser(UserContext.getCurrent());
				this.bidMapper.insert(bid);

				// 2,借款对象:增加投标次数,增加投标金额;
				br.setBidCount(br.getBidCount() + 1);
				br.setCurrentSum(br.getCurrentSum().add(amount));
				// 3,投资人:账户可用余额减少,冻结金额增加,创建投标流水;
				borrowAccount.setUsableAmount(borrowAccount.getUsableAmount().subtract(amount));
				borrowAccount.setFreezedAmount(borrowAccount.getFreezedAmount().add(amount));
				this.flowService.createBidFlow(borrowAccount, bid);
				// 如果标投满了
				if (br.getCurrentSum().compareTo(br.getBidRequestAmount()) == 0) {
					// 1,修改借款状态为风控终审;
					br.setBidRequestState(Constants.BIDREQUEST_STATE_APPROVE_PENDING_1);
					// 2,修改投标状态;
					this.bidMapper.updateStates(br.getId(), Constants.BIDREQUEST_STATE_APPROVE_PENDING_1);
				}

				this.accountService.update(borrowAccount);
				this.update(br);
			}
		}
	}

	@Override
	public void fullAudit1(Long id, int state, String remark) {
		// 判断,借款处于满标一审状态
		BidRequest br = this.get(id);
		if (br != null && br.getBidRequestState() == Constants.BIDREQUEST_STATE_APPROVE_PENDING_1) {
			// 1,创建借款审核对象,设置对应参数;
			this.createBidRequestAuditHistory(br, remark, state, BidRequestAuditHistory.AUDIT_FULL1);
			// 如果审核通过
			if (state == BidRequestAuditHistory.STATE_PASS) {
				// 1,修改借款状态为财务终审
				br.setBidRequestState(Constants.BIDREQUEST_STATE_APPROVE_PENDING_2);
				// 2,修改投标对象状态
				this.bidMapper.updateStates(br.getId(), Constants.BIDREQUEST_STATE_APPROVE_PENDING_2);
			} else {
				moneyCallback(br);
			}
			this.update(br);
		}
	}

	/**
	 * 满标审核拒绝,退款
	 * 
	 * @param br
	 */
	private void moneyCallback(BidRequest br) {
		// 如果审核拒绝
		// 1,修改借款状态为满审拒绝
		br.setBidRequestState(Constants.BIDREQUEST_STATE_REJECTED);
		// 2,修改投标对象状态
		this.bidMapper.updateStates(br.getId(), Constants.BIDREQUEST_STATE_REJECTED);
		// 3,遍历投标对象
		for (Bid bid : br.getBids()) {
			// 4,投标人账户可用余额增加,冻结金额减少
			Account bidAccount = this.accountService.get(bid.getBidUser().getId());
			bidAccount.setFreezedAmount(bidAccount.getFreezedAmount().subtract(bid.getAvailableAmount()));
			bidAccount.setUsableAmount(bidAccount.getUsableAmount().add(bid.getAvailableAmount()));
			// 5,增加投标失败流水
			this.flowService.createBidFaildFlow(bidAccount, bid);
			this.accountService.update(bidAccount);
		}
		// 6,借款人状态吗移除
		UserInfo borrowUser = this.userinfoService.get(br.getCreateUser().getId());
		borrowUser.removeState(BitStateUtil.HAS_BIDREQUEST_IN_PROCESS);
		this.userinfoService.update(borrowUser);
	}

	@Override
	public void fullAudit2(Long id, int state, String remark) {
		// 检查,判断是否处于财务终审
		BidRequest br = this.get(id);
		if (br != null && br.getBidRequestState() == Constants.BIDREQUEST_STATE_APPROVE_PENDING_2) {
			// 创建审核对象,设置相关属性
			this.createBidRequestAuditHistory(br, remark, state, BidRequestAuditHistory.AUDIT_FULL2);
			// 审核通过
			if (state == BidRequestAuditHistory.STATE_PASS) {
				// 1,对于借款对象本身
				// 1.1,修改借款的状态,还款中;
				br.setBidRequestState(Constants.BIDREQUEST_STATE_PAYING_BACK);
				// 1.2,修改投标的状态;
				this.bidMapper.updateStates(br.getId(), Constants.BIDREQUEST_STATE_PAYING_BACK);
				// 2,对于借款人?
				Account borrowAccount = this.accountService.get(br.getCreateUser().getId());
				// 2.1,借款成功,可用余额增加;
				borrowAccount.setUsableAmount(borrowAccount.getUsableAmount().add(br.getBidRequestAmount()));
				// 2.2,生成借款成功流水
				this.flowService.createBorrowSuccessFlow(borrowAccount, br);
				// 2.3,待还金额增加,
				borrowAccount.setUnReturnAmount(
						borrowAccount.getUnReturnAmount().add(br.getBidRequestAmount()).add(br.getTotalRewardAmount()));
				// 2.4,剩余信用额度减少;
				borrowAccount
						.setRemainBorrowLimit(borrowAccount.getRemainBorrowLimit().subtract(br.getBidRequestAmount()));
				// 2.5,去掉状态吗;
				UserInfo borrowUser = this.userinfoService.get(borrowAccount.getId());
				borrowUser.removeState(BitStateUtil.HAS_BIDREQUEST_IN_PROCESS);

				// 2.6,支付借款手续费,可用余额减少
				BigDecimal manageFee = CalculatetUtil.calAccountManagementCharge(br.getBidRequestAmount());
				borrowAccount.setUsableAmount(borrowAccount.getUsableAmount().subtract(manageFee));
				// 2.7,生成支付流水
				this.flowService.createManageFeeFlow(borrowAccount, br, manageFee);
				// 2.8,系统账户收取借款手续费并生成流水
				this.systemAccountService.chargeManageFee(br, manageFee);
				// 3,对于投资人?
				// 3.1,遍历投标;
				Map<Long, Account> bidAccounts = new HashMap<>();
				for (Bid bid : br.getBids()) {
					// 3.2,投标成功,冻结金额减少
					Long bidAccountId = bid.getBidUser().getId();
					Account bidAccount = bidAccounts.get(bidAccountId);
					if (bidAccount == null) {
						bidAccount = this.accountService.get(bidAccountId);
						bidAccounts.put(bidAccountId, bidAccount);
					}
					bidAccount.setFreezedAmount(bidAccount.getFreezedAmount().subtract(bid.getAvailableAmount()));
					// 3.3,生成投标成功流水;
					this.flowService.createBidSuccessFlow(bidAccount, bid);
				}

				// 4,对于后期业务?
				// 4.1,生成该借款的还款计划对象及对应的还款明细对象
				List<PaymentSchedule> pss = this.createPaymentSchdules(br);
				// 3.4,投资人待收本金/待收利息增加;
				for (PaymentSchedule ps : pss) {
					for (PaymentScheduleDetail psd : ps.getDetails()) {
						Account bidAccount = bidAccounts.get(psd.getInvestorId());
						bidAccount.setUnReceiveInterest(bidAccount.getUnReceiveInterest().add(psd.getInterest()));
						bidAccount.setUnReceivePrincipal(bidAccount.getUnReceivePrincipal().add(psd.getPrincipal()));
					}
				}

				for (Account bidAccount : bidAccounts.values()) {
					this.accountService.update(bidAccount);
				}

				this.accountService.update(borrowAccount);
				this.userinfoService.update(borrowUser);
			} else {
				// 审核拒绝?
				// 1,同满标一审
				this.moneyCallback(br);
			}
			this.update(br);
		}
	}

	/**
	 * 生成还款计划
	 * 
	 * @param br
	 */
	private List<PaymentSchedule> createPaymentSchdules(BidRequest br) {

		List<PaymentSchedule> pss = new ArrayList<>();
		BigDecimal totalPrincipal = Constants.ZERO;
		BigDecimal totalInterest = Constants.ZERO;
		for (int i = 0; i < br.getMonthes2Return(); i++) {
			PaymentSchedule ps = new PaymentSchedule();
			ps.setBidRequestId(br.getId());
			ps.setBidRequestTitle(br.getTitle());
			ps.setBidRequestType(br.getBidRequestType());
			ps.setBorrowUser(br.getCreateUser());
			ps.setDeadLine(DateUtil.addMonths(br.getPublishTime(), i + 1));
			ps.setMonthIndex(i + 1);
			ps.setReturnType(br.getReturnType());
			ps.setState(Constants.PAYMENT_STATE_NORMAL);

			if (i < br.getMonthes2Return() - 1) {
				ps.setTotalAmount(CalculatetUtil.calMonthToReturnMoney(br.getReturnType(), br.getBidRequestAmount(),
						br.getCurrentRate(), i + 1, br.getMonthes2Return()));
				ps.setInterest(CalculatetUtil.calMonthlyInterest(br.getReturnType(), br.getBidRequestAmount(),
						br.getCurrentRate(), i + 1, br.getMonthes2Return()));
				ps.setPrincipal(ps.getTotalAmount().subtract(ps.getInterest()));
				totalPrincipal = totalPrincipal.add(ps.getPrincipal());
				totalInterest = totalInterest.add(ps.getInterest());
			} else {
				// 最后一期
				ps.setPrincipal(br.getBidRequestAmount().subtract(totalPrincipal));
				ps.setInterest(br.getTotalRewardAmount().subtract(totalInterest));
				ps.setTotalAmount(ps.getPrincipal().add(ps.getInterest()));
			}
			this.psMapper.insert(ps);
			// 生成还款计划明细
			this.createPaymentScheduleDetail(ps, br);

			pss.add(ps);
		}
		return pss;
	}

	/**
	 * 生成还款计划明细
	 * 
	 * @param ps
	 * @param br
	 */
	private void createPaymentScheduleDetail(PaymentSchedule ps, BidRequest br) {
		BigDecimal totalPrincipal = Constants.ZERO;
		BigDecimal totalInterest = Constants.ZERO;

		for (int i = 0; i < br.getBidCount(); i++) {
			Bid bid = br.getBids().get(i);
			PaymentScheduleDetail psd = new PaymentScheduleDetail();
			psd.setBidAmount(bid.getAvailableAmount()); // 应该除期数
			psd.setBidId(bid.getId());
			psd.setBidRequestId(br.getId());
			psd.setBorrowUser(br.getCreateUser());
			psd.setDeadLine(ps.getDeadLine());
			psd.setInvestorId(bid.getBidUser().getId());
			psd.setMonthIndex(ps.getMonthIndex());
			psd.setPaymentScheduleId(ps.getId());
			psd.setReturnType(br.getReturnType());

			if (i < br.getBidCount() - 1) {
				BigDecimal rate = bid.getAvailableAmount().divide(br.getBidRequestAmount(), Constants.SCALE_CAL,
						RoundingMode.HALF_UP);
				psd.setPrincipal(
						ps.getPrincipal().multiply(rate).setScale(Constants.SCALE_STORE, RoundingMode.HALF_UP));
				psd.setInterest(ps.getInterest().multiply(rate).setScale(Constants.SCALE_STORE, RoundingMode.HALF_UP));
				psd.setTotalAmount(psd.getPrincipal().add(psd.getInterest()));

				totalPrincipal = totalPrincipal.add(psd.getPrincipal());
				totalInterest = totalInterest.add(psd.getInterest());
			} else {
				// 最后一个投资人
				psd.setPrincipal(ps.getPrincipal().subtract(totalPrincipal));
				psd.setInterest(ps.getInterest().subtract(totalInterest));
				psd.setTotalAmount(psd.getPrincipal().add(psd.getInterest()));
			}
			this.psdMapper.insert(psd);
			ps.getDetails().add(psd);
		}
	}

	@Override
	public void returnMoney(Long id) {
		// 得到还款计划
		PaymentSchedule ps = this.psMapper.selectByPrimaryKey(id);
		AssertUtil.isNotNull(ps, "数据错误");

		Account borrowAccount = this.accountService.get(UserContext.getCurrent().getId());
		// 判断:
		if (ps.getState() == Constants.PAYMENT_STATE_NORMAL// 1,还款计划状态;
				&& ps.getTotalAmount().compareTo(borrowAccount.getUsableAmount()) <= 0// 2,还款金额<=账户可用金额;
				&& ps.getBorrowUser().getId().equals(borrowAccount.getId())// 3,当前用户是还款用户;
		) {
			// 执行还款:
			// 对于还款对象
			// 1,修改还款时间,还款状态;
			ps.setPayDate(new Date());
			ps.setState(Constants.PAYMENT_STATE_DONE);
			this.psMapper.updateByPrimaryKey(ps);
			// 2,批量修改还款明细的还款时间
			this.psdMapper.batchUpdatePayDate(ps.getId(), new Date());
			// 对于借款人
			// 1,账户可用余额减少,生成还款流水;
			borrowAccount.setUsableAmount(borrowAccount.getUsableAmount().subtract(ps.getTotalAmount()));
			this.flowService.createReturnMoneyFlow(borrowAccount, ps);
			// 2,待还金额减少;
			borrowAccount.setUnReturnAmount(borrowAccount.getUnReturnAmount().subtract(ps.getTotalAmount()));
			// 3,剩余授信额度增加;
			borrowAccount.setRemainBorrowLimit(borrowAccount.getRemainBorrowLimit().add(ps.getPrincipal()));

			this.accountService.update(borrowAccount);
			// 对于投资人
			Map<Long, Account> bidAccounts = new HashMap<>();
			List<CreditTransfer> needCancels = new ArrayList<CreditTransfer>();
			for (PaymentScheduleDetail psd : ps.getDetails()) {
				// 1,遍历还款明细;
				// 2,投资人账户可用余额增加;生成收款流水;
				Account bidAccount = bidAccounts.get(psd.getInvestorId());
				if (bidAccount == null) {
					bidAccount = this.accountService.get(psd.getInvestorId());
					bidAccounts.put(bidAccount.getId(), bidAccount);
				}
				bidAccount.setUsableAmount(bidAccount.getUsableAmount().add(psd.getTotalAmount()));
				this.flowService.createReceiveMoneyFlow(bidAccount, psd);
				// 3,待收利息/待收本金减少;
				bidAccount.setUnReceiveInterest(bidAccount.getUnReceiveInterest().subtract(psd.getInterest()));
				bidAccount.setUnReceivePrincipal(bidAccount.getUnReceivePrincipal().subtract(psd.getPrincipal()));
				// 4,支付利息管理费;生成支付流水;
				BigDecimal interestFee = CalculatetUtil.calInterestManagerCharge(psd.getInterest());
				bidAccount.setUsableAmount(bidAccount.getUsableAmount().subtract(interestFee));
				this.flowService.createInterestFeeFlow(bidAccount, psd, interestFee);
				// 5,系统收取利息管理费;生成对应流水;
				this.systemAccountService.chargeInterestFee(psd, interestFee);

				// 处理债权转让的问题
				// 如果还款明细处于转让中,则找到对应的债权标
				if (psd.getIntrans() == Constants.IN_TRANS) {
					CreditTransfer cancel = this.creditTransferService.findNeedCancel(psd.getBidId());
					needCancels.add(cancel);
				}
			}
			for (Account bidAccount : bidAccounts.values()) {
				this.accountService.update(bidAccount);
			}
			// 后续?
			// 判断当前还款是否是最后一期,修改还款状态
			PaymentScheduleQueryObject qo = new PaymentScheduleQueryObject();
			qo.setBidRequestId(ps.getBidRequestId());
			List<PaymentSchedule> pss = this.psMapper.queryData(qo);

			// 撤销债权标
			for (CreditTransfer cancel : needCancels) {
				this.creditTransferService.cancel(cancel);
			}

			boolean flag = true;
			for (PaymentSchedule temp : pss) {
				if (temp.getState() != Constants.PAYMENT_STATE_DONE) {
					flag = false;
					break;
				}
			}
			if (flag) {
				BidRequest br = this.get(ps.getBidRequestId());
				br.setBidRequestState(Constants.BIDREQUEST_STATE_COMPLETE_PAY_BACK);
				// 批量修改投标对象状态
				this.bidMapper.updateStates(br.getId(), Constants.BIDREQUEST_STATE_COMPLETE_PAY_BACK);
				this.update(br);
			}

		}
	}

	@Override
	public void publishInTime() {
		BidRequestQueryObject qo = new BidRequestQueryObject();
		qo.setState(Constants.BIDREQUEST_STATE_PUBLISH_PENDING);
		qo.setPublishTime(new Date());

		List<BidRequest> list = this.bidRequestMapper.queryData(qo);
		for (BidRequest br : list) {
			br.setBidRequestState(Constants.BIDREQUEST_STATE_BIDDING);
			this.update(br);
		}
	}

}
